home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / daten / astrolog / src / getkey.c < prev    next >
C/C++ Source or Header  |  1995-08-11  |  6KB  |  282 lines

  1. /*                                                               -*- C -*-
  2.  *  GETKEY.C
  3.  *
  4.  *  (c)Copyright 1990 by Tobias Ferber,  All Rights Reserved.
  5.  */
  6.  
  7. /* $VER: $Id: getkey.c,v 1.2 1995/07/02 22:21:44 tf Exp $ */
  8.  
  9. #include <stdio.h>
  10. #include "getkey.h"
  11.  
  12.  
  13. /* Note: Turbo C Version 1.0 can *NOT* read from non-buffered streams */
  14.  
  15. #if defined(__TURBOC__)
  16. #undef getkey
  17. #include <conio.h>
  18. int getkey(void) { return getch(); }
  19.  
  20.  
  21. #elif defined(GNUDOS)
  22.  
  23. int getkey(void)
  24. /* read from a non-buffered, binary opened console stream */
  25. {
  26.   FILE *con; /* the console stream */
  27.   int key;
  28.  
  29.   /* you *MUST* open the console in binary mode for DJGPP
  30.    * in order to really get a non-buffered stream via setvbuf()! */
  31.  
  32.   if( con= fopen(CONSOLENAME,"rb") )
  33.   {
  34.     setvbuf(con,0L,_IONBF,0L);  /* better than setbuf(con,0L); ? */ 
  35.  
  36.     if(ferror(con))
  37.       clearerr(con);
  38.  
  39.     fflush(con);
  40.  
  41.     key= (int)fgetc(con);
  42.  
  43.     fclose(con);
  44.   }
  45.   else key= stdin ? (int)fgetc(stdin) : 0;
  46.  
  47.   return key;
  48. }
  49.  
  50.  
  51. #elif defined(__MSDOS__)
  52. #include <dos.h>
  53.  
  54. /*
  55.  * The following stuff is implemented in the c.lib of DJGPP and is
  56.  * Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  57.  *
  58.  *      .globl  _getkey
  59.  * _getkey:
  60.  *      pushl   %ebx
  61.  *      pushl   %esi
  62.  *      pushl   %edi
  63.  *      movb    $0,%ah
  64.  *      int     $0x16
  65.  *      cmpb    $0,%al
  66.  *      jnz     L1
  67.  *      movb    %ah,%al
  68.  *      movb    $1,%ah
  69.  *      jmp     L2
  70.  * L1:
  71.  *      movb    $0,%ah
  72.  * L2:
  73.  *      andl    $0xffff,%eax
  74.  *      popl    %edi
  75.  *      popl    %esi
  76.  *      popl    %ebx
  77.  *      ret
  78.  */
  79.  
  80. int getkey(void)
  81. /* returns the keycode of the last pressed key using BIOS */
  82. {
  83.   union REGS regs;          /* defined in <dos.h> */
  84.   regs.h.ah= 0x10;          /* get MF-II keycode function # */
  85.   int86(0x16,®s,®s);  /* int 16h -> keycode in regs.x.ax */
  86.   return (unsigned short)regs.x.ax;
  87. }
  88.  
  89.  
  90. #elif defined(AMIGA)
  91.  
  92. #include <exec/types.h>
  93. #include <exec/ports.h>
  94. #include <exec/memory.h>
  95. #include <libraries/dos.h>
  96. #include <libraries/dosextens.h>
  97.  
  98. /*
  99.  * Function - SendPacket written by Phil Lindsay, Carolyn Scheppner, and Andy
  100.  * Finkel. This function will send a packet of the given type to the Message
  101.  * Port supplied.
  102.  */
  103.  
  104. typedef struct StandardPacket StandardPacket;
  105.  
  106. long
  107. SendPacket(pid, action, args, nargs)
  108. struct MsgPort *pid;    /* process indentifier ... (handler's message port) */
  109. long action;    /* packet type ... (what you want handler to do) */
  110. long *args;     /* a pointer to an argument list */
  111. long nargs;     /* number of arguments in list */
  112. {
  113.     struct MsgPort *replyport;
  114.     StandardPacket *packet;
  115.     long count, *pargs, res1;
  116.  
  117.     replyport= (struct MsgPort *)CreatePort(NULL, 0L);
  118.     if (!replyport)
  119.       return(0);
  120.  
  121.     /* Allocate space for a packet, make it public and clear it */
  122.  
  123.     packet = (StandardPacket *)
  124.       AllocMem(sizeof(StandardPacket), MEMF_PUBLIC | MEMF_CLEAR);
  125.  
  126.     if (!packet) {
  127.         DeletePort(replyport);
  128.         return(0);
  129.     }
  130.     packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);
  131.     packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
  132.     packet->sp_Pkt.dp_Port = replyport;
  133.     packet->sp_Pkt.dp_Type = action;
  134.  
  135.     /* copy the args into the packet */
  136.  
  137.     pargs = &(packet->sp_Pkt.dp_Arg1);      /* address of first argument */
  138.     for (count = 0; count < nargs; count++)
  139.         pargs[count] = args[count];
  140.  
  141.     PutMsg(pid, &packet->sp_Msg);   /* send packet */
  142.  
  143.     WaitPort(replyport);
  144.     GetMsg(replyport);
  145.  
  146.     res1 = packet->sp_Pkt.dp_Res1;
  147.  
  148.     FreeMem(packet, sizeof(StandardPacket));
  149.     DeletePort(replyport);
  150.  
  151.     return (res1);
  152. }
  153.  
  154. int getkey(void)
  155. {
  156.   int key= 0;  /* the one we're going to return */
  157.   BPTR con;    /* BCPL pointer to a struct FileHandle */
  158.  
  159.   /* We must use Open() here -- not Input() -- because last may
  160.    * be redirected. */
  161.  
  162.   con= Open( CONSOLENAME, MODE_OLDFILE );
  163.  
  164.   if( BADDR(con) && IsInteractive(con) ) 
  165.   {
  166.     struct MsgPort *mp;
  167.     long arg[1], res;
  168.  
  169.     mp = ((struct FileHandle *)(BADDR(con)))->fh_Type;
  170.     arg[0]= -1L;   /* make it RAW */
  171.     res= SendPacket(mp, ACTION_SCREEN_MODE, arg, 1);
  172.  
  173.     if(res)
  174.     {
  175.       char buffer[4];     /* just to be sure... */
  176.       long actualLength;  /* return value */
  177.  
  178.       /* The value returned by Read() is the length of the information
  179.        * actually read.  So when 'actualLength' is > 0, then it is the
  180.        * number of characters read.  A value of zero means that the
  181.        * end-of-file has been reached.  Errors are indicated by a value
  182.        * of -1.  Note:  Read is an unbuffered routine. */
  183.  
  184.       actualLength = Read( con, buffer, (long)sizeof(buffer)-1 );
  185.                                           /* 1 extra (for the bugs) */
  186.       if(actualLength > 0)
  187.         key= (int)buffer[0];
  188.  
  189.       arg[0]= 0L;  /* make it COOKED */
  190.       (void)SendPacket(mp, ACTION_SCREEN_MODE, arg, 1);
  191.     }
  192.  
  193.     /* Note that we must close 'con' again, whereas Input() must NEVER
  194.      * be closed. */
  195.  
  196.     Close(con);
  197.   }
  198.  
  199.   if(!key)
  200.     key= getchar();  /* just to be sure... */
  201.  
  202.   return key;
  203. }
  204.  
  205.  
  206. #elif defined(unix) || defined(__alpha)
  207.  
  208. #include <curses.h>
  209.  
  210. int getkey(void)
  211. {
  212.   char c;
  213.  
  214. #ifdef OBSOLETE
  215.  
  216.   /* try /dev/tty.  If that doesn't work, use file descriptor 2,
  217.    * which in Unix is usually attached to the screen, but also
  218.    * usually lets you read from the keyboard. */
  219.  
  220.   int tty= open("/dev/tty", 0);
  221.   if(tty < 0)
  222.     tty= 2;
  223.  
  224.   { int result;
  225.     do {
  226.       result= read(tty, &c, sizeof(char));
  227.     } while( result != 1 );
  228.   }
  229.  
  230.   if(tty!=2)
  231.     close(tty);
  232.  
  233. #else /* POSIX */
  234.  
  235.   initscr();
  236.   savetty();
  237.   cbreak();
  238.   noecho();
  239.   c= getch();
  240.   resetty();
  241.   endwin();
  242.  
  243. #endif
  244.  
  245.   return c;
  246.  
  247. #endif /* which machine? */
  248.  
  249.  
  250. #ifdef TEST
  251. #include <stdlib.h>
  252.  
  253. main(int argc, char **argv)
  254. {
  255.   int err= 0;
  256.  
  257.   if(argc==2)
  258.   {
  259.     char *s= argv[1];
  260.     do {
  261.       char c= getkey();
  262. #ifdef DEBUG
  263.       printf("getkey() returned 0x%02x\n",c)
  264. #endif
  265.       for(err=0; s[err]!='\0'; err++)
  266.         if(c==s[err])
  267.           break;
  268.     } while(s[err]=='\0');
  269.   }
  270.   else
  271.   { puts("GETKEY [keys]\n\n"
  272.          "GetKey wartet auf eine der Tasten in 'keys' und gibt den\n"
  273.          "Index der gedrueckten Taste aus 'keys' im Errorlevel zurueck");
  274.   }
  275. #ifdef DEBUG
  276.   printf("errorlevel=%d\n",err);
  277. #endif
  278.   exit(err);
  279. }
  280. #endif /* TEST */
  281.